--SceneBase
--create by zouyb
--场景基类

SceneBase = class("SceneBase",function()
    return cc.Scene:create()
end)

function SceneBase.create()
    local scene = SceneBase.new();
    return scene;
end

function SceneBase:ctor()
    --内容根节点
    self.contentRoot = nil;

    --普通窗口根节点
    self.formRoot = nil;

    --模态窗口根节点
    self.dialogRoot = nil;

    --特效根节点
    self.effectRoot = nil;

    --普通窗口
    self.forms = {};

    --模态窗口
    self.dialogs = {};

    --特效层
    self.effects = {};

    self.contentRoot = cc.Layer:create();
    self.contentRoot:setName("contentRoot");
    self:addChild(self.contentRoot);

    self.formRoot = cc.Layer:create();
    self.formRoot:setName("formRoot");
    self:addChild(self.formRoot);

    self.dialogRoot = cc.Layer:create();
    self.dialogRoot:setName("dialogRoot");
    self:addChild(self.dialogRoot);

    self.effectRoot = cc.Layer:create();
    self.effectRoot:setName("effectRoot");
    self:addChild(self.effectRoot);

    local curKey = "";

    -- 增加事件监测层
    local touchDetectLayer = ccui.Layout:create();
    touchDetectLayer:setName("touchDetectLayer");
    touchDetectLayer:setTouchEnabled(true);
    touchDetectLayer:setSwallowTouches(false);
    local frameSize = cc.Director:getInstance():getOpenGLView():getFrameSize();
    touchDetectLayer:setContentSize(frameSize.width, frameSize.height);
    local function onClick(sender, eventType)
        if eventType == ccui.TouchEventType.began then
            if FormFocusM then
                FormFocusM.setUserIdleTime(0);
            end

            if DEBUG_MODE == 1 then
                performWithDelay(touchDetectLayer, function() openGdUI(); end, 5);
            end
            return false;
        elseif eventType == ccui.TouchEventType.ended or eventType == ccui.TouchEventType.canceled then
            touchDetectLayer:stopAllActions();
        end
    end
    touchDetectLayer:addTouchEventListener(onClick);
    self:addChild(touchDetectLayer);
end

--添加内容节点
function SceneBase:addContent(c)
    self.contentRoot:addChild(c);
    c.root = self;
end

--删除内容节点
function SceneBase:removeContent(c)
    self.contentRoot:removeChild(c);
    c.root = nil;
end

--返回内容根节点
function SceneBase:getContentRoot()
    return self.contentRoot;
end

-- 播放窗口出现特效
function playAppearEffect(form)
    local formName = form:getName();
    local appearEffect = FormEffectM.query(formName, "appear");

    local function checkFormEffect()
        if DEBUG_MODE == 1 and appearEffect == nil then
            error("请在form_effect.csv中配置"..form:getName().."的窗口效果！！");
        end
    end

    local status, msg = xpcall(checkFormEffect, function(msg) return msg.."\n"..debug.traceback(); end)
    if not status then
        recordTraceback(msg);
    end

    FormEffectM.setAppearEffect(form, appearEffect);
    FormEffectM.runAppearEffect(form);
end

-- 播放窗口消失特效
function playDisappearEffect(form, callback)
    local disappearEffect = FormEffectM.query(form:getName(), "disappear");
    if disappearEffect ~= nil and disappearEffect ~= "" then
        FormEffectM.setDisappearEffect(form, disappearEffect);
        FormEffectM.runDisppearEffect(form, callback);
    else
        callback();
    end
end


--添加窗口
--static为true时，表示该窗口为常驻窗口
function SceneBase:addForm(form, static, noApearEffect)
    if _G["gameScene"] then
        -- 特殊场景
        local name = form:getName();
        self.formRoot:addChild(form);
        if static == nil or static == false then
            table.insert(self.forms, form);
        end
        form.root = self;
        return;
    end

    local name = form:getName();
    EventMgr.fire(event.BEFORE_ADD_FORM, { name = name, });

    self.formRoot:addChild(form);
    -- 播放窗口出现动画
    if not noApearEffect then
        playAppearEffect(form);
    end

    if static == nil or static == false then
        table.insert(self.forms, form);
    end

    form.root = self;

    EventMgr.fire(event.ADD_FORM, { name = name, });

    -- AudioM.playFx("ui_open1");
end

--删除窗口
function SceneBase:removeForm(form, withoutEffect)
    if _G["gameScene"] then
        -- 特殊场景
        local name = form:getName();
        self.formRoot:removeChild(form);
        table.removeItem(self.forms, form);
        form.root = nil;
        return;
    end

    local function callback()
        local name = form:getName();
        self.formRoot:removeChild(form);
        table.removeItem(self.forms, form);
        form.root = nil;
        EventMgr.fire(event.REMOVE_FORM, { name = name, });
    end

    -- 播放窗口消失动画
    if not withoutEffect then
        -- 播放窗口消失动画
        playDisappearEffect(form, callback);
    else
        callback();
    end
end

--删除所有非常驻窗口
function SceneBase:removeNonStaticForms()
    for i = 1, #self.forms do
        self.formRoot:removeChild(self.forms[i]);
    end
    self.forms = {};
end

--显示窗口
function SceneBase:showForm(form)
    form:setVisible(true);
end

--隐藏窗口
function SceneBase:hideForm(form)
    form:setVisbile(false);
end

--判断窗口是否已显示
function SceneBase:isOpen(formName)
   for i = 1, #self.forms do
      local form = self.forms[i];
      if form ~= nil and form:getName() == formName then
          return true;
      end
   end
   return false;
end

-- 根据名字获取相对应的窗口
function SceneBase:getFormByName(formName)
    local target = nil;
    for i = 1, #self.forms do
        local form = self.forms[i];
        if form ~= nil and form:getName() == formName then
            target = form;
            break;
        end
    end

    return target;
end

--根据名字删除对应窗口
function SceneBase:removeFormByName(formName, withoutEffect)
    local target = nil;
    for i = 1, #self.forms do
        local form = self.forms[i];
        if form ~= nil and form:getName() == formName then
            target = form;
            break;
        end
    end

    withoutEffect = withoutEffect or false;
    if target ~= nil then
        self:removeForm(target, withoutEffect);
    end
end

-- 移除不在列表中的其他界面
function SceneBase:removeAllFormWithoutList(formList)
    local targetList = {};

    for i = #self.forms, 1, -1 do
        local form = self.forms[i];

        if form ~= nil and not IsInTable(form:getName(), formList) then
            table.insert(targetList, form:getName());
        end
    end

    for i = 1, #targetList do
        self:removeFormByName(targetList[i], true);
    end
end

-- 获得当前窗口, 即最新addForm的窗口
function SceneBase:getCurrentForm()
    local num = #self.forms;
    if num == 0 then
        return nil;
    end

    return self.forms[num];
end

-- 获得上一个窗口，指盖在当前窗口底下的那个窗口
function SceneBase:getPrevForm()
    local num = #self.forms;
    if num <= 1 then
        return nil;
    end

    return self.forms[num - 1];
end

--添加模态窗口
function SceneBase:addDialog(dialog)
    self.dialogRoot:addChild(dialog);
    playAppearEffect(dialog);

    table.insert(self.dialogs, dialog);
    dialog.root = self;

    EventMgr.fire(event.ADD_DIALOG, { name = dialog:getName(), });
end

--删除模态窗口
function SceneBase:removeDialog(dialog)
    local function callback()
        local name = dialog:getName();
        self.dialogRoot:removeChild(dialog);
        table.removeItem(self.dialogs, dialog);
        dialog.root = nil;

        EventMgr.fire(event.REMOVE_DIALOG, { name = name, });
    end
    playDisappearEffect(dialog, callback);
end

-- 获得当前模态窗口, 即最新addDialog的窗口
function SceneBase:getCurrentDialog()
    local num = #self.dialogs;
    if num == 0 then
        return nil;
    end

    return self.dialogs[num];
end

--添加特效节点
function SceneBase:addEffect(node)
    self.effectRoot:addChild(node);
    table.insert(self.effects, node);
end

--删除特效节点
function SceneBase:removeEffect(node)
    self.effectRoot:removeChild(node);
    table.removeItem(self.effects, node);
end

-- 获取特效根节点
function SceneBase:getEffectRoot()
    return self.effectRoot;
end

--显示窗口列表
function SceneBase:printFormList()
    print("--------------------------------")
    for i = 1, #self.forms do
        local form = self.forms[i];
        print(form:getName());
    end
    print("================================")
end

function getName()
    return "SceneBase";
end

return SceneBase
